/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.landmark;

import java.io.File;
import java.io.FileWriter;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Vector;
import javax.swing.JOptionPane;
import javax.swing.JTextArea;
import javax.swing.SwingWorker;
import org.htmlparser.Node;
import org.htmlparser.Parser;
import org.htmlparser.filters.HasAttributeFilter;
import org.htmlparser.nodes.TagNode;
import org.htmlparser.nodes.TextNode;
import org.htmlparser.util.NodeIterator;
import org.htmlparser.util.NodeList;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

/**
 *
 * @author computer
 */
public class FenixCat extends SwingWorker<Boolean, Boolean> {

    FileWriter fw = null;
    FileWriter fwErrorFile = null;
    StringBuffer sb = new StringBuffer();
    Hashtable<String, String> htModelLinks = new Hashtable<String, String>();
    Hashtable<String, String> htImageUrls = new Hashtable<String, String>();
    JTextArea txtArea;
    String status = "";

    @Override
    protected Boolean doInBackground() throws Exception {
        start();
        return true;
    }

    @Override
    protected void done() {
        JOptionPane.showMessageDialog(Util.getHelperBean().getDataPanel(), status);
        Util.getHelperBean().setTerminateCurrentProcess(false);
        Util.getHelperBean().getToggleButton().setEnabled(false);
    }

    /**
     * @param args
     */
    public void start() {
        try {
            String dirName = "./outputs";
            String largeImages = "./output/Fenix/LargeImages/";

            Util.createDirectory(dirName);
            Util.createDirectory(largeImages);
            txtArea = Util.createOutputFile("Fenix");

            fw = new FileWriter(Util.getHelperBean().getOutputFile());
            fwErrorFile = new FileWriter(Util.getHelperBean().getErrorFile());
            HelperBean helperBean = Util.getHelperBean();
            // Process the all products page to get the main category links which are on the left side menu of the page            

            String productsUrl = "http://www.fenixlighting.com/products/all_products.html";

            processHomePageLinks(productsUrl);
            Enumeration modelEnum = htModelLinks.keys();

            txtArea.append("\nFiles are located at : " + helperBean.getOutputFile().getAbsolutePath() + "\n" + helperBean.getErrorFile().getAbsolutePath() + "\n");
            txtArea.append("Total products : " + htModelLinks.size() + "\n");

            while (modelEnum.hasMoreElements()) {
                if (Util.getHelperBean().isTerminateCurrentProcess()) {
                    break;
                }

                sb = new StringBuffer();
                String key = (String) modelEnum.nextElement();

                txtArea.append("Processing page: " + key + "\n");
                txtArea.paintImmediately(txtArea.getVisibleRect());

                fw.write("\n");
                processModel(htModelLinks.get(key));
                getImages(htModelLinks.get(key));

                String str = sb.toString();
                str = str.replaceAll("\r", "").replaceAll("\n", "").replaceAll("   ", "").replaceAll("<tr>", "\n<tr>").replaceAll(",", "&#44;");

                fw.write(str);
                fw.flush();
            }

            modelEnum = htImageUrls.keys();
            while (modelEnum.hasMoreElements()) {
                if (Util.getHelperBean().isTerminateCurrentProcess()) {
                    break;
                }
                String key = (String) modelEnum.nextElement();
                getImages(htImageUrls.get(key));
            }

            if (fw != null) {
                fw.close();
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (fw != null) {
                    fw.close();
                }
            } catch (Exception e1) {
                // TODO: handle exception
            }
        }
        status = "Done processing.";
        if (Util.getHelperBean().isTerminateCurrentProcess()) {
            status = "Process Terminated";
        }
        txtArea.append("\n" + status);
    }

    private Elements getElements(Document doc) throws Exception {
        String[] idKeywords = {"div#center_col_xtralong", "div#center_col_long", "div#center_col_xtra_xtralong", "div#center_col"};
        Elements elements = null;
        for (String str : idKeywords) {
            elements = doc.select(str);
            if (elements.size() == 0) {
                continue;
            } else {
                break;
            }
        }
        return elements;
    }

    private void getImages(String aUrl) {
        try {
            Document doc = Jsoup.connect(aUrl).get();

            Elements elements = getElements(doc).select("a[href]");
            System.out.println(elements.size());
            // to know which URL/model we have the data for in the final output/file
            for (Element element : elements) {
                String url = element.attr("abs:href");
                System.out.println(aUrl);
                if (url.substring(url.lastIndexOf(".")+1, url.length()).equalsIgnoreCase("html")) {
                    System.out.println("substr");
                    htImageUrls.put(url, url);
                } else {
                    loadAndSaveImagesFromPage(elements.attr("abs:href"));
                }
            }
        } catch (Exception e) {
            try {
                fwErrorFile.write(aUrl + " \n" + e.getMessage() + " \n");
                fwErrorFile.flush();
                e.printStackTrace();
            } catch (Exception e1) {
                // TODO: handle exception
            }
        }
    }

    private void loadAndSaveImagesFromPage(String largeImageUrl) {

        String largeFile = largeImageUrl.substring(largeImageUrl.lastIndexOf("/"), largeImageUrl.length());
        //File thumbNailImageFile = new File("./output/Moteng/ThumbnailImages/" + thumbFile);
        File largeImageFile = new File("./output/Fenix/LargeImages/" + largeFile);
        try {

            if (!largeImageFile.exists()) {
                Util.saveImage(largeImageUrl, "./output/Fenix/LargeImages/",null);
            }

        } catch (Exception e) {
            try {
                fwErrorFile.append(largeImageUrl);
                fwErrorFile.flush();
            } catch (Exception e1) {
            }
        }
    }

    private boolean processModel(String aUrl) {
        boolean status = false;
        try {
            Parser parser = Util.getParserFromUrl(aUrl, null);

            // to know which URL/model we have the data for in the final output/file
            fw.write(aUrl + "\n");

            NodeList nl = getNodeListFromAttributeFilter(parser);

            for (int i = 0; i < nl.size(); i++) {
                Node targetTableNode = nl.elementAt(i);// retrives the table content where the description starts which we are intersetd in.			
                iterateTag(targetTableNode);
            }
        } catch (Exception e) {
            try {
                fwErrorFile.write(aUrl + " \n" + e.getMessage() + " \n");
                fwErrorFile.flush();
                e.printStackTrace();
            } catch (Exception e1) {
                // TODO: handle exception
            }
        }
        return status;
    }

    private NodeList getNodeListFromAttributeFilter(Parser parser) throws Exception {
        String[] idKeywords = {"center_col_xtralong", "center_col_long", "center_col_xtra_xtralong", "center_col"};
        NodeList nl = null;
        for (String str : idKeywords) {
            parser.setInputHTML(Util.getHelperBean().getInputHTML().toString());
            parser.setEncoding("UTF-8");

            nl = parser.parse(new HasAttributeFilter("id", str));

            if (nl.size() == 0) {
                continue;
            } else {
                break;
            }
        }
        return nl;
    }

    private void iterateTag(Node aNode) throws Exception {
        if (aNode instanceof TextNode) {
            // downcast to TextNode
            TextNode text = (TextNode) aNode;

            sb.append(text.getText());// manipulating for table data which contains commas in one column
        } else if (aNode instanceof TagNode) {
            // downcast to TagNode
            TagNode tag = (TagNode) aNode;

            if (tag.getRawTagName().equalsIgnoreCase("li")) {
                sb.append("<li>");
            }
            if (tag.getRawTagName().equalsIgnoreCase("p")) {
                sb.append("<p>");
            }
            if (tag.getRawTagName().equalsIgnoreCase("br")) {
                sb.append("<br>");
            }
            if (tag.getRawTagName().equalsIgnoreCase("tr")) {
                sb.append("<tr>");
            }
            if (tag.getRawTagName().equalsIgnoreCase("td")) {
                sb.append("<td>");
            }
            // process recursively (nodes within nodes) via getChildren()				
            NodeList nl = tag.getChildren();
            if (null != nl) {
                try {
                    for (NodeIterator i = nl.elements(); i.hasMoreNodes();) {
                        iterateTag(i.nextNode());
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }

    private void processHomePageLinks(String aUrl) {
        try {
            Document doc = Jsoup.connect(aUrl).get();
            Elements catSubElements = doc.select("a[href]");
            for (Element element : catSubElements) {
                String str = element.attr("abs:href");
                int lastUnderScore = str.lastIndexOf("_");
                String[] productAccessories = {"diffuser_lens.html", "bike_mount.html", "diffuser_tip.html", "filter_adapter.html", "tk_camping_shade.html"};
                Vector productsList = new Vector();
                for (String product : productAccessories) {
                    productsList.add(product);
                }
                if (productsList.contains(str.substring(str.lastIndexOf("/") + 1, str.length()))) {
                    htModelLinks.put(element.attr("abs:href"), element.attr("abs:href"));
                }
                if ((str.contains("/products/") && lastUnderScore == -1)) {
                    htModelLinks.put(element.attr("abs:href"), element.attr("abs:href"));
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
